#ifndef _MEMBLOCK_H_CSEAPI_
#define _MEMBLOCK_H_CSEAPI_

#ifdef SEEK_SET
  #define SEEK_SET                 0
#endif

#ifndef SEEK_CUR
  #define SEEK_CUR                 1
#endif

#ifndef SEEK_END
  #define SEEK_END                 2
#endif

class CSE_IMPEXP_IN TAbsStream
{
public:
    virtual TBool isEnd(size_t position);
    virtual size_t seek(int offset, int origin);
    virtual size_t tell();
    virtual size_t read(char *buffer, size_t count);
    virtual size_t write(const char *buffer, size_t count);
    virtual void flush();
};

class CSE_IMPEXP_IN TMemAbsStream: public TAbsStream
{
public:
    virtual char *addr();
    virtual int len();
};

class CSE_IMPEXP_IN TFixedStream: public TMemAbsStream
{
protected:
    char *m_data;
    size_t m_position;
    size_t m_length;

public:
    TFixedStream();
    TFixedStream(char *buff, size_t iLen);
    ~TFixedStream();

    TFixedStream& operator=(const TFixedStream& stream);

    char *addr();
    int len();

    TBool isEnd(size_t position);
    size_t seek(int offset, int origin);
    size_t tell();
    size_t read(char *buffer, size_t count);
    size_t write(const char *buffer, size_t count);
};

class TIntArray;  // forward declare
class TCharArray; // forward declare

class CSE_IMPEXP_IN TSizedStream: public TMemAbsStream
{
protected:
    TIntArray *m_data;
    size_t m_position;
    size_t m_length;

public:
    TSizedStream();
    TSizedStream(const TCharArray& str);
    ~TSizedStream();

    void resize(int iNewSize);
    char *addr();
    int len();

    TBool isEnd(size_t position);
    size_t seek(int offset, int origin);
    size_t tell();
    size_t read(char *buffer, size_t count);
    size_t write(const char *buffer, size_t count);
};

class CSE_IMPEXP_IN TMemBlock
{
private:
    TMemBlock(const TMemBlock& block); // disable copy construct

protected:
    TChar *m_data;

public:
    TMemBlock();
    TMemBlock(int iSize);
    TMemBlock(int MagicNum, TMemBlock& block);
    TMemBlock(TChar *addr);
    ~TMemBlock();

    // create TMemBlock and share memory with TFixedStream
    TMemBlock(TFixedStream& stream, int iSize);

    operator TChar*() const;
    TChar& operator[](int index) const;
    TMemBlock slice(int index, int iLen) const;  // create new and copy slice

    TBool isEmpty() const;
    TChar *addr() const;
    TChar *transfer(TChar *pOther);
};

class CSE_IMPEXP_IN TUniMemBlock
{   // TAnsiBlock use TChar unit (iSize,index,iLen...)
private:
    TUniMemBlock(const TUniMemBlock& block); // disable copy construct
    
protected:
    TWchar *m_data;

public:
    TUniMemBlock();
    TUniMemBlock(int iSize);
    TUniMemBlock(int MagicNum, TUniMemBlock& block);
    TUniMemBlock(TWchar *addr);
    ~TUniMemBlock();
    
    // create TUniMemBlock and share memory with TFixedStream
    TUniMemBlock(TFixedStream& stream, int iSize);

    operator TWchar*() const;
    TWchar& operator[](int index) const;

    TUniMemBlock slice(int index, int iLen) const;
    TBool isEmpty() const;
    TWchar *addr() const;
    TWchar *transfer(TWchar *pOther);
};

#endif
